#include <iostream>

using std::cout;
using std::endl;
using std::ostream;

class Complex;

class Point {
public:
    //explicit关键字的作用是禁止隐式转换
    explicit
    Point(int ix = 0, int iy = 0)
    : _ix(ix)
    , _iy(iy)
    {
        cout << "Point(int,int)" << endl;
    }

    Point(const Complex &rhs);

    void print() const
    {
        cout << "(" << _ix 
             << "," << _iy
             << ")" << endl;
    }

    friend ostream & operator<<(ostream &os, const Point & rhs);
    
private:
    int _ix;
    int _iy;
};

ostream & operator<<(ostream &os, const Point & rhs)
{
    os << "(" << rhs._ix
       << "," << rhs._iy
       << ")";
    return os;
}

class Complex
{
public:
    Complex(double dreal, double dimage)
    : _dreal(dreal)
    , _dimage(dimage)
    {   cout << "Complex(double,double)" << endl;   }

    void print() const
    {
        cout << _dreal << " + " << _dimage << " i" << endl;
    }

#if 1
    //添加类型转换函数
    //除非有特别的要求，一般情况下不要轻易使用
    //这会影响代码的可读性
    operator Point(){
        cout << "operator Point()" << endl;
        return Point(_dreal, _dimage);
    }
#endif

    operator int(){
        cout << "operator int()" << endl;
        return _dreal;
    }

    //友元函数之普通函数
    //推荐使用
    friend Complex operator+(const Complex &, const Complex &);

    //左操作数(对象本身)发生了变化, 其返回值使用了引用形式
    Complex & operator+=(const Complex & rhs)
    {
        cout << "operator+=(const Complex &)" << endl;
        _dreal += rhs._dreal;
        _dimage += rhs._dimage;
        return *this;
    }

    //自增运算符的前置形式
    Complex & operator++()
    {
        ++_dreal;
        ++_dimage;
        return *this;
    }

    Complex operator++(int x)
    {//对于后置的写法，添加一个参数,代表他是后置形式
        Complex tmp(*this);
        ++_dreal;
        ++_dimage;
        cout << "x:" << x << endl;
        return tmp;
    }

    friend Point;
    friend ostream & operator<<(ostream & os, const Complex & rhs);
private:
    double _dreal;
    double _dimage;
};

//运算符重载之友元函数(普通函数)
Complex operator+(const Complex & lhs, const Complex & rhs)
{
    Complex tmp(lhs._dreal + rhs._dreal, lhs._dimage + rhs._dimage);
    return tmp;
}

ostream & operator<<(ostream & os, const Complex & rhs)
{
    os << rhs._dreal << " + " << rhs._dimage << "i";
    return os;
}


Point::Point(const Complex &rhs)
: _ix(rhs._dreal)
, _iy(rhs._dimage)
{
    cout << "Point(const Complex &)" << endl;
}

int main()
{
    Complex c1(1, 2);
    cout << "c1:" << c1 << endl;
    Point pt = c1;
    cout << "pt:" << pt << endl;

    //可读性不强
    int x = c1;
    cout << "x:" << x << endl;
    Point pt2(10, 11);
    pt2 = c1;
    cout <<"pt2:" << pt2 << endl;

    return 0;
}

